package com.example.powernodemall.TokenFilter;


import com.example.powernodemall.Config.PathConfig;
import com.example.powernodemall.ProjectEnum.ResultEnum;
import com.example.powernodemall.constant.BaseConstant;
import com.example.powernodemall.model.Result;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.annotation.Resource;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class AuthTokenFilter implements GlobalFilter, Ordered {
    @Resource
    PathConfig pathConfig;
    @Resource
    StringRedisTemplate stringRedisTemplate;
    @Resource
    ObjectMapper objectMapper;
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest serverHttpRequest = exchange.getRequest();
        if (pathConfig.getWhitePath().contains(serverHttpRequest.getURI().getPath())) {
            return chain.filter(exchange);
        }
        String authorization = serverHttpRequest.getHeaders().getFirst("Authorization");
        if (authorization != null && authorization.startsWith(BaseConstant.ToKen_Prefix)) {
           authorization = authorization.substring(7);
           if (!authorization.isBlank()&& Boolean.TRUE.equals(stringRedisTemplate.hasKey(BaseConstant.Redis_Token_Prefix + authorization))) {
               return chain.filter(exchange);
           }
        }
        ServerHttpResponse serverHttpResponse = exchange.getResponse();
        serverHttpResponse.getHeaders().set(BaseConstant.ContentType,BaseConstant.ContentJson);
        Result<Object> failure = Result.Failure(ResultEnum.NO_AUTHORIZATION);
        DataBuffer dataBuffer=null;
        try {
            dataBuffer = serverHttpResponse.bufferFactory().wrap(objectMapper.writeValueAsBytes(failure));
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        return  serverHttpResponse.writeWith(Mono.just(dataBuffer));
    }

    @Override
    public int getOrder() {
        return -5;
    }
}
